package cn.royan.fl.services 
{
	import cn.royan.fl.events.NetworkEvent;
	import cn.royan.fl.interfaces.INetworkProtocol;
	import cn.royan.fl.utils.CryptoCode;
	import cn.royan.fl.utils.Logger;
	import flash.events.Event;
	import flash.events.EventDispatcher;
	import flash.events.IOErrorEvent;
	import flash.events.ProgressEvent;
	import flash.events.SecurityErrorEvent;
	import flash.net.Socket;
	
	/**
	 * ...
	 * @author RoYan
	 */
	public class ClientSocketProtocol extends EventDispatcher implements INetworkProtocol 
	{
		private var socket:Socket;
		private var host:String;
		private var port:int;
		
		public function ClientSocketProtocol( host:String, port:int ) 
		{
			super();
			
			this.host = host;
			this.port = port;
		}
		
		public function sendRequest( request:* = null, extra:* = null ):void
		{
			if ( socket && socket.connected ) {
				socket.writeUTFBytes( CryptoCode.encrypt( request ) );
				socket.flush();
			}
		}
		
		public function connect():void
		{
			disconnect();
			
			Logger.tracer( "SOCKET TRY CONNECT host:" + host +" port:"+ port );
			socket = new Socket();
			socket.addEventListener( Event.CONNECT, 					connectHandler );
			socket.addEventListener( Event.CLOSE, 						closeHandler );
			socket.addEventListener( IOErrorEvent.IO_ERROR, 			ioerrorHandler );
			socket.addEventListener( ProgressEvent.SOCKET_DATA, 		progressHandler );
			socket.addEventListener( SecurityErrorEvent.SECURITY_ERROR,	securityErrorHandler );
			socket.connect( host, port );
		}
		
		public function disconnect():void
		{
			if ( socket && socket.connected )
			socket.close();
		}
		
		private function connectHandler(evt:Event):void
		{
			Logger.tracer( "SOCKET CONNECTED" );
			dispatchEvent( new NetworkEvent( NetworkEvent.NETWORK_CONNECT ) );
		}
		
		private function closeHandler(evt:Event):void
		{
			Logger.tracer( "SOCKET CLOSED" );
			dispatchEvent( new NetworkEvent( NetworkEvent.NETWORK_CLOSE ) );
		}
		
		private function progressHandler(evt:ProgressEvent):void
		{
			Logger.tracer( "SOCKET DATA" );
			
			var packet:String = CryptoCode.decrypt( socket.readUTFBytes( socket.bytesAvailable ) );
			if( packet.lastIndexOf( "<cross-domain-policy>") == -1 ){
				packet = CryptoCode.decrypt( packet );
			}
			
			dispatchEvent( new NetworkEvent( NetworkEvent.NETWORK_PACKET ) );
		}
		
		private function ioerrorHandler(evt:IOErrorEvent):void
		{
			Logger.tracer( "SOCKET ERROR" );
			dispatchEvent( new NetworkEvent( NetworkEvent.NETWORK_ERROR ) );
		}
		
		private function securityErrorHandler(evt:SecurityErrorEvent):void
		{
			Logger.tracer( "SOCKET SECURITY ERROR" );
			dispatchEvent( new NetworkEvent( NetworkEvent.NETWORK_ERROR ) );
		}
		
		public function getData():*
		{
			
		}
	}

}